home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / sound / sn76477.c < prev    next >
C/C++ Source or Header  |  2000-04-23  |  32KB  |  1,036 lines

  1. /*****************************************************************************
  2.   SN76477 pins and assigned interface variables/functions
  3.  
  4.                                 SN76477_envelope_w()
  5.                                /                    \
  6.                        [ 1] ENV SEL 1            ENV SEL 2 [28]
  7.                        [ 2] GND                   MIXER C [27] \
  8.  SN76477_noise_clock_w [ 3] NOISE EXT OSC          MIXER A [26]    > SN76477_mixer_w()
  9.           noise_res    [ 4] RES NOISE OSC          MIXER B [25] /
  10.          filter_res    [ 5] NOISE FILTER RES      O/S RES [24] oneshot_res
  11.          filter_cap    [ 6] NOISE FILTER CAP      O/S CAP [23] oneshot_cap
  12.           decay_res    [ 7] DECAY RES              VCO SEL [22] SN76477_vco_w()
  13.    attack_decay_cap    [ 8] A/D CAP               SLF CAP [21] slf_cap
  14.  SN76477_enable_w()    [ 9] ENABLE                  SLF RES [20] slf_res
  15.          attack_res    [10] ATTACK RES                PITCH [19] pitch_voltage
  16.       amplitude_res    [11] AMP                   VCO RES [18] vco_res
  17.        feedback_res    [12] FEEDBACK              VCO CAP [17] vco_cap
  18.                        [13] OUTPUT             VCO EXT CONT [16] vco_voltage
  19.                        [14] Vcc               +5V REG OUT [15]
  20.  
  21.     All resistor values in Ohms.
  22.     All capacitor values in Farads.
  23.     Use RES_K, RES_M and CAP_U, CAP_N, CAP_P macros to convert
  24.     magnitudes, eg. 220k = RES_K(220), 47nF = CAP_N(47)
  25.  
  26.  *****************************************************************************/
  27.  
  28. #include "driver.h"
  29.  
  30. #define VERBOSE 1
  31.  
  32. #if VERBOSE >= 0
  33. #define LOG(n,x) if( VERBOSE >= (n) ) logerror x
  34. #else
  35. #define LOG(n,x)
  36. #endif
  37.  
  38. #if MAME_DEBUG
  39. #define CHECK_CHIP_NUM                        \
  40.     if( chip >= intf->num )                 \
  41.     {                                        \
  42.         LOG(0,("SN76477 #%d: fatal, only %d chips defined in interface!\n", chip, intf->num)); \
  43.         return;                             \
  44.     }
  45.  
  46. #define CHECK_CHIP_NUM_AND_RANGE(BITS,FUNC) \
  47.     CHECK_CHIP_NUM;                         \
  48.     if( data != (data & BITS) )             \
  49.         LOG(0,("SN76477 #%d: warning %s called with data = $%02X!\n", chip, #FUNC, data)); \
  50.     data &= BITS;
  51. #else
  52. #define CHECK_CHIP_NUM
  53. #define CHECK_CHIP_NUM_AND_RANGE(BITS,FUNC)
  54. #endif
  55.  
  56.  
  57. #define VMIN    0x0000
  58. #define VMAX    0x7fff
  59.  
  60. struct SN76477 {
  61.     int channel;            /* returned by stream_init() */
  62.  
  63.     int samplerate;         /* from Machine->sample_rate */
  64.     int vol;                /* current volume (attack/decay) */
  65.     int vol_count;            /* volume adjustment counter */
  66.     int vol_rate;            /* volume adjustment rate - dervied from attack/decay */
  67.     int vol_step;            /* volume adjustment step */
  68.  
  69.     double slf_count;        /* SLF emulation */
  70.     double slf_freq;        /* frequency - derived */
  71.     double slf_level;        /* triangular wave level */
  72.     int slf_dir;            /* triangular wave direction */
  73.     int slf_out;            /* rectangular output signal state */
  74.  
  75.     double vco_count;        /* VCO emulation */
  76.     double vco_freq;        /* frequency - derived */
  77.     double vco_step;        /* modulated frequency - derived */
  78.     int vco_out;            /* rectangular output signal state */
  79.  
  80.     int noise_count;        /* NOISE emulation */
  81.     int noise_clock;        /* external clock signal */
  82.     int noise_freq;         /* filter frequency - derived */
  83.     int noise_poly;         /* polynome */
  84.     int noise_out;            /* rectangular output signal state */
  85.  
  86.     void *envelope_timer;    /* ENVELOPE timer */
  87.     int envelope_state;     /* attack / decay toggle */
  88.  
  89.     double attack_time;     /* ATTACK time (time until vol reaches 100%) */
  90.     double decay_time;        /* DECAY time (time until vol reaches 0%) */
  91.     double oneshot_time;    /* ONE-SHOT time */
  92.     void *oneshot_timer;    /* ONE-SHOT timer */
  93.  
  94.     int envelope;            /* pin    1, pin 28 */
  95.     double noise_res;        /* pin    4 */
  96.     double filter_res;        /* pin    5 */
  97.     double filter_cap;        /* pin    6 */
  98.     double decay_res;        /* pin    7 */
  99.     double attack_decay_cap;/* pin    8 */
  100.     int enable;             /* pin    9 */
  101.     double attack_res;        /* pin 10 */
  102.     double amplitude_res;    /* pin 11 */
  103.     double feedback_res;    /* pin 12 */
  104.     double vco_voltage;     /* pin 16 */
  105.     double vco_cap;         /* pin 17 */
  106.     double vco_res;         /* pin 18 */
  107.     double pitch_voltage;    /* pin 19 */
  108.     double slf_res;         /* pin 20 */
  109.     double slf_cap;         /* pin 21 */
  110.     int vco_select;         /* pin 22 */
  111.     double oneshot_cap;     /* pin 23 */
  112.     double oneshot_res;     /* pin 24 */
  113.     int mixer;                /* pin 25,26,27 */
  114.  
  115.     INT16 vol_lookup[VMAX+1-VMIN];    /* volume lookup table */
  116. };
  117.  
  118. static struct SN76477interface *intf;
  119. static struct SN76477 *sn76477[MAX_SN76477];
  120.  
  121. static void attack_decay(int param)
  122. {
  123.     struct SN76477 *sn = sn76477[param];
  124.     sn->envelope_state ^= 1;
  125.     if( sn->envelope_state )
  126.     {
  127.         /* start ATTACK */
  128.         sn->vol_rate = ( sn->attack_time > 0 ) ? VMAX / sn->attack_time : VMAX;
  129.         sn->vol_step = +1;
  130.         LOG(2,("SN76477 #%d: ATTACK rate %d/%d = %d/sec\n", param, sn->vol_rate, sn->samplerate, sn->vol_rate/sn->samplerate));
  131.     }
  132.     else
  133.     {
  134.         /* start DECAY */
  135.         sn->vol = VMAX; /* just in case... */
  136.         sn->vol_rate = ( sn->decay_time > 0 ) ? VMAX / sn->decay_time : VMAX;
  137.         sn->vol_step = -1;
  138.         LOG(2,("SN76477 #%d: DECAY rate %d/%d = %d/sec\n", param, sn->vol_rate, sn->samplerate, sn->vol_rate/sn->samplerate));
  139.     }
  140. }
  141.  
  142. static void vco_envelope_cb(int param)
  143. {
  144.     attack_decay(param);
  145. }
  146.  
  147. static void oneshot_envelope_cb(int param)
  148. {
  149.     struct SN76477 *sn = sn76477[param];
  150.     sn->oneshot_timer = NULL;
  151.     attack_decay(param);
  152. }
  153.  
  154. #if VERBOSE
  155. static const char *mixer_mode[8] = {
  156.     "VCO",
  157.     "SLF",
  158.     "Noise",
  159.     "VCO/Noise",
  160.     "SLF/Noise",
  161.     "SLF/VCO/Noise",
  162.     "SLF/VCO",
  163.     "Inhibit"
  164. };
  165. #endif
  166.  
  167. /*****************************************************************************
  168.  * set MIXER select inputs
  169.  *****************************************************************************/
  170. void SN76477_mixer_w(int chip, int data)
  171. {
  172.     struct SN76477 *sn = sn76477[chip];
  173.  
  174.     CHECK_CHIP_NUM_AND_RANGE(7,SN76477_mixer_w);
  175.  
  176.     if( data == sn->mixer )
  177.         return;
  178.     stream_update(sn->channel, 0);
  179.     sn->mixer = data;
  180.     LOG(1,("SN76477 #%d: MIXER mode %d [%s]\n", chip, sn->mixer, mixer_mode[sn->mixer]));
  181. }
  182.  
  183. void SN76477_mixer_a_w(int chip, int data)
  184. {
  185.     struct SN76477 *sn = sn76477[chip];
  186.  
  187.     CHECK_CHIP_NUM_AND_RANGE(1,SN76477_mixer_a_w);
  188.  
  189.     data = data ? 1 : 0;
  190.     if( data == (sn->mixer & 1) )
  191.         return;
  192.     stream_update(sn->channel, 0);
  193.     sn->mixer = (sn->mixer & ~1) | data;
  194.     LOG(1,("SN76477 #%d: MIXER mode %d [%s]\n", chip, sn->mixer, mixer_mode[sn->mixer]));
  195. }
  196.  
  197. void SN76477_mixer_b_w(int chip, int data)
  198. {
  199.     struct SN76477 *sn = sn76477[chip];
  200.  
  201.     CHECK_CHIP_NUM_AND_RANGE(1,SN76477_mixer_b_w);
  202.  
  203.     data = data ? 2 : 0;
  204.     if( data == (sn->mixer & 2) )
  205.         return;
  206.     stream_update(sn->channel, 0);
  207.     sn->mixer = (sn->mixer & ~2) | data;
  208.     LOG(1,("SN76477 #%d: MIXER mode %d [%s]\n", chip, sn->mixer, mixer_mode[sn->mixer]));
  209. }
  210.  
  211. void SN76477_mixer_c_w(int chip, int data)
  212. {
  213.     struct SN76477 *sn = sn76477[chip];
  214.  
  215.     CHECK_CHIP_NUM_AND_RANGE(1,SN76477_mixer_c_w);
  216.  
  217.     data = data ? 4 : 0;
  218.     if( data == (sn->mixer & 4) )
  219.         return;
  220.     stream_update(sn->channel, 0);
  221.     sn->mixer = (sn->mixer & ~4) | data;
  222.     LOG(1,("SN76477 #%d: MIXER mode %d [%s]\n", chip, sn->mixer, mixer_mode[sn->mixer]));
  223. }
  224.  
  225. #if VERBOSE
  226. static const char *envelope_mode[4] = {
  227.     "VCO",
  228.     "One-Shot",
  229.     "Mixer only",
  230.     "VCO with alternating Polarity"
  231. };
  232. #endif
  233.  
  234. /*****************************************************************************
  235.  * set ENVELOPE select inputs
  236.  *****************************************************************************/
  237. void SN76477_envelope_w(int chip, int data)
  238. {
  239.     struct SN76477 *sn = sn76477[chip];
  240.  
  241.     CHECK_CHIP_NUM_AND_RANGE(3,SN76477_envelope_w);
  242.  
  243.     if( data == sn->envelope )
  244.         return;
  245.     stream_update(sn->channel, 0);
  246.     sn->envelope = data;
  247.     LOG(1,("SN76477 #%d: ENVELOPE mode %d [%s]\n", chip, sn->envelope, envelope_mode[sn->envelope]));
  248. }
  249.  
  250. void SN76477_envelope_1_w(int chip, int data)
  251. {
  252.     struct SN76477 *sn = sn76477[chip];
  253.  
  254.     CHECK_CHIP_NUM_AND_RANGE(1,SN76477_envelope_1_w);
  255.  
  256.     if( data == (sn->envelope & 1) )
  257.         return;
  258.     stream_update(sn->channel, 0);
  259.     sn->envelope = (sn->envelope & ~1) | data;
  260.     LOG(1,("SN76477 #%d: ENVELOPE mode %d [%s]\n", chip, sn->envelope, envelope_mode[sn->envelope]));
  261. }
  262.  
  263. void SN76477_envelope_2_w(int chip, int data)
  264. {
  265.     struct SN76477 *sn = sn76477[chip];
  266.  
  267.     CHECK_CHIP_NUM_AND_RANGE(1,SN76477_envelope_2_w);
  268.  
  269.     data <<= 1;
  270.  
  271.     if( data == (sn->envelope & 2) )
  272.         return;
  273.     stream_update(sn->channel, 0);
  274.     sn->envelope = (sn->envelope & ~2) | data;
  275.     LOG(1,("SN76477 #%d: ENVELOPE mode %d [%s]\n", chip, sn->envelope, envelope_mode[sn->envelope]));
  276. }
  277.  
  278. /*****************************************************************************
  279.  * set VCO external/SLF input
  280.  *****************************************************************************/
  281. void SN76477_vco_w(int chip, int data)
  282. {
  283.     struct SN76477 *sn = sn76477[chip];
  284.  
  285.     CHECK_CHIP_NUM_AND_RANGE(1,SN76477_vco_w);
  286.  
  287.     if( data == sn->vco_select )
  288.         return;
  289.     stream_update(sn->channel, 0);
  290.     sn->vco_select = data;
  291.     LOG(1,("SN76477 #%d: VCO select %d [%s]\n", chip, sn->vco_select, sn->vco_select ? "Internal (SLF)" : "External (Pin 16)"));
  292. }
  293.  
  294. /*****************************************************************************
  295.  * set VCO enable input
  296.  *****************************************************************************/
  297. void SN76477_enable_w(int chip, int data)
  298. {
  299.     struct SN76477 *sn = sn76477[chip];
  300.  
  301.     CHECK_CHIP_NUM_AND_RANGE(1,SN76477_enable_w);
  302.  
  303.     if( data == sn->enable )
  304.         return;
  305.     stream_update(sn->channel, 0);
  306.     sn->enable = data;
  307.     sn->envelope_state = data;
  308.     if( sn->envelope_timer )
  309.         timer_remove(sn->envelope_timer);
  310.     sn->envelope_timer = NULL;
  311.     if( sn->oneshot_timer )
  312.         timer_remove(sn->oneshot_timer);
  313.     sn->oneshot_timer = NULL;
  314.     if( sn->enable == 0 )
  315.     {
  316.         switch( sn->envelope )
  317.         {
  318.         case 0: /* VCO */
  319.             if( sn->vco_res > 0 && sn->vco_cap > 0 )
  320.                 sn->envelope_timer = timer_pulse(TIME_IN_HZ(0.64/(sn->vco_res * sn->vco_cap)), chip, vco_envelope_cb);
  321.             else
  322.                 oneshot_envelope_cb(chip);
  323.             break;
  324.         case 1: /* One-Shot */
  325.             oneshot_envelope_cb(chip);
  326.             if (sn->oneshot_time > 0)
  327.                 sn->oneshot_timer = timer_set(sn->oneshot_time, chip, oneshot_envelope_cb);
  328.             break;
  329.         case 2: /* MIXER only */
  330.             sn->vol = VMAX;
  331.             break;
  332.         default:  /* VCO with alternating polariy */
  333.             /* huh? */
  334.             if( sn->vco_res > 0 && sn->vco_cap > 0 )
  335.                 sn->envelope_timer = timer_pulse(TIME_IN_HZ(0.64/(sn->vco_res * sn->vco_cap)/2), chip, vco_envelope_cb);
  336.             else
  337.                 oneshot_envelope_cb(chip);
  338.             break;
  339.         }
  340.     }
  341.     else
  342.     {
  343.         switch( sn->envelope )
  344.         {
  345.         case 0: /* VCO */
  346.             if( sn->vco_res > 0 && sn->vco_cap > 0 )
  347.                 sn->envelope_timer = timer_pulse(TIME_IN_HZ(0.64/(sn->vco_res * sn->vco_cap)), chip, vco_envelope_cb);
  348.             else
  349.                 oneshot_envelope_cb(chip);
  350.             break;
  351.         case 1: /* One-Shot */
  352.             oneshot_envelope_cb(chip);
  353.             break;
  354.         case 2: /* MIXER only */
  355.             sn->vol = VMIN;
  356.             break;
  357.         default:  /* VCO with alternating polariy */
  358.             /* huh? */
  359.             if( sn->vco_res > 0 && sn->vco_cap > 0 )
  360.                 sn->envelope_timer = timer_pulse(TIME_IN_HZ(0.64/(sn->vco_res * sn->vco_cap)/2), chip, vco_envelope_cb);
  361.             else
  362.                 oneshot_envelope_cb(chip);
  363.             break;
  364.         }
  365.     }
  366.     LOG(1,("SN76477 #%d: ENABLE line %d [%s]\n", chip, sn->enable, sn->enable ? "Inhibited" : "Enabled" ));
  367. }
  368.  
  369. /*****************************************************************************
  370.  * set NOISE external signal (pin 3)
  371.  *****************************************************************************/
  372. void SN76477_noise_clock_w(int chip, int data)
  373. {
  374.     struct SN76477 *sn = sn76477[chip];
  375.  
  376.     CHECK_CHIP_NUM_AND_RANGE(1,SN76477_noise_clock_w);
  377.  
  378.     if( data == sn->noise_clock )
  379.         return;
  380.     stream_update(sn->channel, 0);
  381.     sn->noise_clock = data;
  382.     /* on the rising edge shift the polynome */
  383.     if( sn->noise_clock )
  384.         sn->noise_poly = ((sn->noise_poly << 7) + (sn->noise_poly >> 10) + 0x18000) & 0x1ffff;
  385. }
  386.  
  387. /*****************************************************************************
  388.  * set NOISE resistor (pin 4)
  389.  *****************************************************************************/
  390. void SN76477_set_noise_res(int chip, double res)
  391. {
  392.     struct SN76477 *sn = sn76477[chip];
  393.  
  394.     CHECK_CHIP_NUM;
  395.  
  396.     stream_update(sn->channel, 0);
  397.     sn->noise_res = res;
  398. }
  399.  
  400. /*****************************************************************************
  401.  * set NOISE FILTER resistor (pin 5)
  402.  *****************************************************************************/
  403. void SN76477_set_filter_res(int chip, double res)
  404. {
  405.     struct SN76477 *sn = sn76477[chip];
  406.  
  407.     CHECK_CHIP_NUM;
  408.  
  409.     if( res == sn->filter_res )
  410.         return;
  411.     stream_update(sn->channel, 0);
  412.     sn->filter_res = res;
  413.     if( sn->filter_res > 0 && sn->filter_cap > 0 )
  414.     {
  415.         sn->noise_freq = (int)(1.28 / (sn->filter_res * sn->filter_cap));
  416.         LOG(1,("SN76477 #%d: NOISE FILTER freqency %d\n", chip, sn->noise_freq));
  417.     }
  418.     else
  419.         sn->noise_freq = sn->samplerate;
  420. }
  421.  
  422. /*****************************************************************************
  423.  * set NOISE FILTER capacitor (pin 6)
  424.  *****************************************************************************/
  425. void SN76477_set_filter_cap(int chip, double cap)
  426. {
  427.     struct SN76477 *sn = sn76477[chip];
  428.  
  429.     CHECK_CHIP_NUM;
  430.  
  431.     if( cap == sn->filter_cap )
  432.         return;
  433.     stream_update(sn->channel, 0);
  434.     sn->filter_cap = cap;
  435.     if( sn->filter_res > 0 && sn->filter_cap > 0 )
  436.     {
  437.         sn->noise_freq = (int)(1.28 / (sn->filter_res * sn->filter_cap));
  438.         LOG(1,("SN76477 #%d: NOISE FILTER freqency %d\n", chip, sn->noise_freq));
  439.     }
  440.     else
  441.         sn->noise_freq = sn->samplerate;
  442. }
  443.  
  444. /*****************************************************************************
  445.  * set DECAY resistor (pin 7)
  446.  *****************************************************************************/
  447. void SN76477_set_decay_res(int chip, double res)
  448. {
  449.     struct SN76477 *sn = sn76477[chip];
  450.  
  451.     CHECK_CHIP_NUM;
  452.  
  453.     if( res == sn->decay_res )
  454.         return;
  455.     stream_update(sn->channel, 0);
  456.     sn->decay_res = res;
  457.     sn->decay_time = sn->decay_res * sn->attack_decay_cap;
  458.     LOG(1,("SN76477 #%d: DECAY time is %fs\n", chip, sn->decay_time));
  459. }
  460.  
  461. /*****************************************************************************
  462.  * set ATTACK/DECAY capacitor (pin 8)
  463.  *****************************************************************************/
  464. void SN76477_set_attack_decay_cap(int chip, double cap)
  465. {
  466.     struct SN76477 *sn = sn76477[chip];
  467.  
  468.     CHECK_CHIP_NUM;
  469.  
  470.     if( cap == sn->attack_decay_cap )
  471.         return;
  472.     stream_update(sn->channel, 0);
  473.     sn->attack_decay_cap = cap;
  474.     sn->decay_time = sn->decay_res * sn->attack_decay_cap;
  475.     sn->attack_time = sn->attack_res * sn->attack_decay_cap;
  476.     LOG(1,("SN76477 #%d: ATTACK time is %fs\n", chip, sn->attack_time));
  477.     LOG(1,("SN76477 #%d: DECAY time is %fs\n", chip, sn->decay_time));
  478. }
  479.  
  480. /*****************************************************************************
  481.  * set ATTACK resistor (pin 10)
  482.  *****************************************************************************/
  483. void SN76477_set_attack_res(int chip, double res)
  484. {
  485.     struct SN76477 *sn = sn76477[chip];
  486.  
  487.     CHECK_CHIP_NUM;
  488.  
  489.     if( res == sn->attack_res )
  490.         return;
  491.     stream_update(sn->channel, 0);
  492.     sn->attack_res = res;
  493.     sn->attack_time = sn->attack_res * sn->attack_decay_cap;
  494.     LOG(1,("SN76477 #%d: ATTACK time is %fs\n", chip, sn->attack_time));
  495. }
  496.  
  497. /*****************************************************************************
  498.  * set AMP resistor (pin 11)
  499.  *****************************************************************************/
  500. void SN76477_set_amplitude_res(int chip, double res)
  501. {
  502.     struct SN76477 *sn = sn76477[chip];
  503.     int i;
  504.  
  505.     CHECK_CHIP_NUM;
  506.  
  507.     if( res == sn->amplitude_res )
  508.         return;
  509.     stream_update(sn->channel, 0);
  510.     sn->amplitude_res = res;
  511.     if( sn->amplitude_res > 0 )
  512.     {
  513. #if VERBOSE
  514.         int clip = 0;
  515. #endif
  516.         for( i = 0; i < VMAX+1; i++ )
  517.         {
  518.             int vol = (int)((3.4 * sn->feedback_res / sn->amplitude_res) * 32767 * i / (VMAX+1));
  519. #if VERBOSE
  520.             if( vol > 32767 && !clip )
  521.                 clip = i;
  522.             LOG(3,("%d\n", vol));
  523. #endif
  524.             if( vol > 32767 ) vol = 32767;
  525.             sn->vol_lookup[i] = vol * intf->mixing_level[chip] / 100;
  526.         }
  527.         LOG(1,("SN76477 #%d: volume range from -%d to +%d (clip at %d%%)\n", chip, sn->vol_lookup[VMAX-VMIN], sn->vol_lookup[VMAX-VMIN], clip * 100 / 256));
  528.     }
  529.     else
  530.     {
  531.         memset(sn->vol_lookup, 0, sizeof(sn->vol_lookup));
  532.     }
  533. }
  534.  
  535. /*****************************************************************************
  536.  * set FEEDBACK resistor (pin 12)
  537.  *****************************************************************************/
  538. void SN76477_set_feedback_res(int chip, double res)
  539. {
  540.     struct SN76477 *sn = sn76477[chip];
  541.     int i;
  542.  
  543.     CHECK_CHIP_NUM;
  544.  
  545.     if( res == sn->feedback_res )
  546.         return;
  547.     stream_update(sn->channel, 0);
  548.     sn->feedback_res = res;
  549.     if( sn->amplitude_res > 0 )
  550.     {
  551. #if VERBOSE
  552.         int clip = 0;
  553. #endif
  554.         for( i = 0; i < VMAX+1; i++ )
  555.         {
  556.             int vol = (int)((3.4 * sn->feedback_res / sn->amplitude_res) * 32767 * i / (VMAX+1));
  557. #if VERBOSE
  558.             if( vol > 32767 && !clip ) clip = i;
  559. #endif
  560.             if( vol > 32767 ) vol = 32767;
  561.             sn->vol_lookup[i] = vol * intf->mixing_level[chip] / 100;
  562.         }
  563.         LOG(1,("SN76477 #%d: volume range from -%d to +%d (clip at %d%%)\n", chip, sn->vol_lookup[VMAX-VMIN], sn->vol_lookup[VMAX-VMIN], clip * 100 / 256));
  564.     }
  565.     else
  566.     {
  567.         memset(sn->vol_lookup, 0, sizeof(sn->vol_lookup));
  568.     }
  569. }
  570.  
  571. /*****************************************************************************
  572.  * set PITCH voltage (pin 19)
  573.  * TODO: fill with live...
  574.  *****************************************************************************/
  575. void SN76477_set_pitch_voltage(int chip, double voltage)
  576. {
  577.     struct SN76477 *sn = sn76477[chip];
  578.  
  579.     CHECK_CHIP_NUM;
  580.  
  581.     if( voltage == sn->pitch_voltage )
  582.         return;
  583.     stream_update(sn->channel, 0);
  584.     sn->pitch_voltage = voltage;
  585.     LOG(1,("SN76477 #%d: VCO pitch voltage %f (%d%% duty cycle)\n", chip, sn->pitch_voltage, 0));
  586. }
  587.  
  588. /*****************************************************************************
  589.  * set VCO resistor (pin 18)
  590.  *****************************************************************************/
  591. void SN76477_set_vco_res(int chip, double res)
  592. {
  593.     struct SN76477 *sn = sn76477[chip];
  594.  
  595.     CHECK_CHIP_NUM;
  596.  
  597.     if( res == sn->vco_res )
  598.         return;
  599.     stream_update(sn->channel, 0);
  600.     sn->vco_res = res;
  601.     if( sn->vco_res > 0 && sn->vco_cap > 0 )
  602.     {
  603.         sn->vco_freq = 0.64 / (sn->vco_res * sn->vco_cap);
  604.         LOG(1,("SN76477 #%d: VCO freqency %f\n", chip, sn->vco_freq));
  605.     }
  606.     else
  607.         sn->vco_freq = 0;
  608. }
  609.  
  610. /*****************************************************************************
  611.  * set VCO capacitor (pin 17)
  612.  *****************************************************************************/
  613. void SN76477_set_vco_cap(int chip, double cap)
  614. {
  615.     struct SN76477 *sn = sn76477[chip];
  616.  
  617.     CHECK_CHIP_NUM;
  618.  
  619.     if( cap == sn->vco_cap )
  620.         return;
  621.     stream_update(sn->channel, 0);
  622.     sn->vco_cap = cap;
  623.     if( sn->vco_res > 0 && sn->vco_cap > 0 )
  624.     {
  625.         sn->vco_freq = 0.64 / (sn->vco_res * sn->vco_cap);
  626.         LOG(1,("SN76477 #%d: VCO freqency %f\n", chip, sn->vco_freq));
  627.     }
  628.     else
  629.         sn->vco_freq = 0;
  630. }
  631.  
  632. /*****************************************************************************
  633.  * set VCO voltage (pin 16)
  634.  *****************************************************************************/
  635. void SN76477_set_vco_voltage(int chip, double voltage)
  636. {
  637.     struct SN76477 *sn = sn76477[chip];
  638.  
  639.     CHECK_CHIP_NUM;
  640.  
  641.     if( voltage == sn->vco_voltage )
  642.         return;
  643.     stream_update(sn->channel, 0);
  644.     sn->vco_voltage = voltage;
  645.     LOG(1,("SN76477 #%d: VCO ext. voltage %f (%f * %f = %f Hz)\n", chip,
  646.         sn->vco_voltage,
  647.         sn->vco_freq,
  648.         10.0 * (5.0 - sn->vco_voltage) / 5.0,
  649.         sn->vco_freq * 10.0 * (5.0 - sn->vco_voltage) / 5.0));
  650. }
  651.  
  652. /*****************************************************************************
  653.  * set SLF resistor (pin 20)
  654.  *****************************************************************************/
  655. void SN76477_set_slf_res(int chip, double res)
  656. {
  657.     struct SN76477 *sn = sn76477[chip];
  658.  
  659.     CHECK_CHIP_NUM;
  660.  
  661.     if( res == sn->slf_res )
  662.         return;
  663.     stream_update(sn->channel, 0);
  664.     sn->slf_res = res;
  665.     if( sn->slf_res > 0 && sn->slf_cap > 0 )
  666.     {
  667.         sn->slf_freq = 0.64 / (sn->slf_res * sn->slf_cap);
  668.         LOG(1,("SN76477 #%d: SLF freqency %f\n", chip, sn->slf_freq));
  669.     }
  670.     else
  671.         sn->slf_freq = 0;
  672. }
  673.  
  674. /*****************************************************************************
  675.  * set SLF capacitor (pin 21)
  676.  *****************************************************************************/
  677. void SN76477_set_slf_cap(int chip, double cap)
  678. {
  679.     struct SN76477 *sn = sn76477[chip];
  680.  
  681.     CHECK_CHIP_NUM;
  682.  
  683.     if( cap == sn->slf_cap )
  684.         return;
  685.     stream_update(sn->channel, 0);
  686.     sn->slf_cap = cap;
  687.     if( sn->slf_res > 0 && sn->slf_cap > 0 )
  688.     {
  689.         sn->slf_freq = 0.64 / (sn->slf_res * sn->slf_cap);
  690.         LOG(1,("SN76477 #%d: SLF freqency %f\n", chip, sn->slf_freq));
  691.     }
  692.     else
  693.         sn->slf_freq = 0;
  694. }
  695.  
  696. /*****************************************************************************
  697.  * set ONESHOT resistor (pin 24)
  698.  *****************************************************************************/
  699. void SN76477_set_oneshot_res(int chip, double res)
  700. {
  701.     struct SN76477 *sn = sn76477[chip];
  702.  
  703.     CHECK_CHIP_NUM;
  704.     if( res == sn->oneshot_res )
  705.         return;
  706.     sn->oneshot_res = res;
  707.     sn->oneshot_time = 0.8 * sn->oneshot_res * sn->oneshot_cap;
  708.     LOG(1,("SN76477 #%d: ONE-SHOT time %fs\n", chip, sn->oneshot_time));
  709. }
  710.  
  711. /*****************************************************************************
  712.  * set ONESHOT capacitor (pin 23)
  713.  *****************************************************************************/
  714. void SN76477_set_oneshot_cap(int chip, double cap)
  715. {
  716.     struct SN76477 *sn = sn76477[chip];
  717.  
  718.     CHECK_CHIP_NUM;
  719.  
  720.     if( cap == sn->oneshot_cap )
  721.         return;
  722.     sn->oneshot_cap = cap;
  723.     sn->oneshot_time = 0.8 * sn->oneshot_res * sn->oneshot_cap;
  724.     LOG(1,("SN76477 #%d: ONE-SHOT time %fs\n", chip, sn->oneshot_time));
  725. }
  726.  
  727. #define UPDATE_SLF                                                            \
  728.     /*************************************                                    \
  729.      * SLF super low frequency oscillator                                    \
  730.      * frequency = 0.64 / (r_slf * c_slf)                                    \
  731.      *************************************/                                 \
  732.     sn->slf_count -= sn->slf_freq;                                            \
  733.     while( sn->slf_count <= 0 )                                             \
  734.     {                                                                        \
  735.         sn->slf_count += sn->samplerate;                                    \
  736.         sn->slf_out ^= 1;                                                    \
  737.     }
  738.  
  739. #define UPDATE_VCO                                                            \
  740.     /************************************                                    \
  741.      * VCO voltage controlled oscilator                                     \
  742.      * min. freq = 0.64 / (r_vco * c_vco)                                    \
  743.      * freq. range is approx. 10:1                                            \
  744.      ************************************/                                    \
  745.     if( sn->vco_select )                                                    \
  746.     {                                                                        \
  747.         /* VCO is controlled by SLF */                                        \
  748.         if( sn->slf_dir == 0 )                                                \
  749.         {                                                                    \
  750.             sn->slf_level -= sn->slf_freq * 2 * 5.0 / sn->samplerate;        \
  751.             if( sn->slf_level <= 0.0 )                                        \
  752.             {                                                                \
  753.                 sn->slf_level = 0.0;                                        \
  754.                 sn->slf_dir = 1;                                            \
  755.             }                                                                \
  756.         }                                                                    \
  757.         else                                                                \
  758.         if( sn->slf_dir == 1 )                                                \
  759.         {                                                                    \
  760.             sn->slf_level += sn->slf_freq * 2 * 5.0 / sn->samplerate;        \
  761.             if( sn->slf_level >= 5.0 )                                        \
  762.             {                                                                \
  763.                 sn->slf_level = 5.0;                                        \
  764.                 sn->slf_dir = 0;                                            \
  765.             }                                                               \
  766.         }                                                                   \
  767.         sn->vco_step = sn->vco_freq * sn->slf_level;                        \
  768.     }                                                                        \
  769.     else                                                                    \
  770.     {                                                                        \
  771.         /* VCO is controlled by external voltage */                         \
  772.         sn->vco_step = sn->vco_freq * sn->vco_voltage;                        \
  773.     }                                                                        \
  774.     sn->vco_count -= sn->vco_step;                                            \
  775.     while( sn->vco_count <= 0 )                                             \
  776.     {                                                                        \
  777.         sn->vco_count += sn->samplerate;                                    \
  778.         sn->vco_out ^= 1;                                                    \
  779.     }
  780.  
  781. #define UPDATE_NOISE                                                        \
  782.     /*************************************                                    \
  783.      * NOISE pseudo rand number generator                                    \
  784.      *************************************/                                 \
  785.     if( sn->noise_res > 0 )                                                 \
  786.         sn->noise_poly = ( (sn->noise_poly << 7) +                            \
  787.                            (sn->noise_poly >> 10) +                         \
  788.                            0x18000 ) & 0x1ffff;                             \
  789.                                                                             \
  790.     /* low pass filter: sample every noise_freq pseudo random value */        \
  791.     sn->noise_count -= sn->noise_freq;                                        \
  792.     while( sn->noise_count <= 0 )                                            \
  793.     {                                                                        \
  794.         sn->noise_count = sn->samplerate;                                    \
  795.         sn->noise_out = sn->noise_poly & 1;                                 \
  796.     }
  797.  
  798. #define UPDATE_VOLUME                                                        \
  799.     /*************************************                                    \
  800.      * VOLUME adjust for attack/decay                                        \
  801.      *************************************/                                 \
  802.     sn->vol_count -= sn->vol_rate;                                            \
  803.     if( sn->vol_count <= 0 )                                                \
  804.     {                                                                        \
  805.         int n = - sn->vol_count / sn->samplerate + 1; /* number of steps */ \
  806.         sn->vol_count += n * sn->samplerate;                                \
  807.         sn->vol += n * sn->vol_step;                                        \
  808.         if( sn->vol < VMIN ) sn->vol = VMIN;                                \
  809.         if( sn->vol > VMAX ) sn->vol = VMAX;                                \
  810.         LOG(3,("SN76477 #%d: vol = $%04X\n", chip, sn->vol));      \
  811.     }
  812.  
  813.  
  814. /*****************************************************************************
  815.  * mixer select 0 0 0 : VCO
  816.  *****************************************************************************/
  817. static void SN76477_update_0(int chip, INT16 *buffer, int length)
  818. {
  819.     struct SN76477 *sn = sn76477[chip];
  820.     while( length-- )
  821.     {
  822.         UPDATE_VCO;
  823.         UPDATE_VOLUME;
  824.         *buffer++ = sn->vco_out ? sn->vol_lookup[sn->vol-VMIN] : -sn->vol_lookup[sn->vol-VMIN];
  825.     }
  826. }
  827.  
  828. /*****************************************************************************
  829.  * mixer select 0 0 1 : SLF
  830.  *****************************************************************************/
  831. static void SN76477_update_1(int chip, INT16 *buffer, int length)
  832. {
  833.     struct SN76477 *sn = sn76477[chip];
  834.     while( length-- )
  835.     {
  836.         UPDATE_SLF;
  837.         UPDATE_VOLUME;
  838.         *buffer++ = sn->slf_out ? sn->vol_lookup[sn->vol-VMIN] : -sn->vol_lookup[sn->vol-VMIN];
  839.     }
  840. }
  841.  
  842. /*****************************************************************************
  843.  * mixer select 0 1 0 : NOISE
  844.  *****************************************************************************/
  845. static void SN76477_update_2(int chip, INT16 *buffer, int length)
  846. {
  847.     struct SN76477 *sn = sn76477[chip];
  848.     while( length-- )
  849.     {
  850.         UPDATE_NOISE;
  851.         UPDATE_VOLUME;
  852.         *buffer++ = sn->noise_out ? sn->vol_lookup[sn->vol-VMIN] : -sn->vol_lookup[sn->vol-VMIN];
  853.     }
  854. }
  855.  
  856. /*****************************************************************************
  857.  * mixer select 0 1 1 : VCO and NOISE
  858.  *****************************************************************************/
  859. static void SN76477_update_3(int chip, INT16 *buffer, int length)
  860. {
  861.     struct SN76477 *sn = sn76477[chip];
  862.     while( length-- )
  863.     {
  864.         UPDATE_VCO;
  865.         UPDATE_NOISE;
  866.         UPDATE_VOLUME;
  867.         *buffer++ = (sn->vco_out & sn->noise_out) ? sn->vol_lookup[sn->vol-VMIN] : -sn->vol_lookup[sn->vol-VMIN];
  868.     }
  869. }
  870.  
  871. /*****************************************************************************
  872.  * mixer select 1 0 0 : SLF and NOISE
  873.  *****************************************************************************/
  874. static void SN76477_update_4(int chip, INT16 *buffer, int length)
  875. {
  876.     struct SN76477 *sn = sn76477[chip];
  877.     while( length-- )
  878.     {
  879.         UPDATE_SLF;
  880.         UPDATE_NOISE;
  881.         UPDATE_VOLUME;
  882.         *buffer++ = (sn->slf_out & sn->noise_out) ? sn->vol_lookup[sn->vol-VMIN] : -sn->vol_lookup[sn->vol-VMIN];
  883.     }
  884. }
  885.  
  886. /*****************************************************************************
  887.  * mixer select 1 0 1 : VCO, SLF and NOISE
  888.  *****************************************************************************/
  889. static void SN76477_update_5(int chip, INT16 *buffer, int length)
  890. {
  891.     struct SN76477 *sn = sn76477[chip];
  892.     while( length-- )
  893.     {
  894.         UPDATE_SLF;
  895.         UPDATE_VCO;
  896.         UPDATE_NOISE;
  897.         UPDATE_VOLUME;
  898.         *buffer++ = (sn->vco_out & sn->slf_out & sn->noise_out) ? sn->vol_lookup[sn->vol-VMIN] : -sn->vol_lookup[sn->vol-VMIN];
  899.     }
  900. }
  901.  
  902. /*****************************************************************************
  903.  * mixer select 1 1 0 : VCO and SLF
  904.  *****************************************************************************/
  905. static void SN76477_update_6(int chip, INT16 *buffer, int length)
  906. {
  907.     struct SN76477 *sn = sn76477[chip];
  908.     while( length-- )
  909.     {
  910.         UPDATE_SLF;
  911.         UPDATE_VCO;
  912.         UPDATE_VOLUME;
  913.         *buffer++ = (sn->vco_out & sn->slf_out) ? sn->vol_lookup[sn->vol-VMIN] : -sn->vol_lookup[sn->vol-VMIN];
  914.     }
  915. }
  916.  
  917. /*****************************************************************************
  918.  * mixer select 1 1 1 : Inhibit
  919.  *****************************************************************************/
  920. static void SN76477_update_7(int chip, INT16 *buffer, int length)
  921. {
  922.     while( length-- )
  923.         *buffer++ = 0;
  924. }
  925.  
  926. static void SN76477_sound_update(int param, INT16 *buffer, int length)
  927. {
  928.     struct SN76477 *sn = sn76477[param];
  929.     if( sn->enable )
  930.     {
  931.         SN76477_update_7(param,buffer,length);
  932.     }
  933.     else
  934.     {
  935.         switch( sn->mixer )
  936.         {
  937.         case 0:
  938.             SN76477_update_0(param,buffer,length);
  939.             break;
  940.         case 1:
  941.             SN76477_update_1(param,buffer,length);
  942.             break;
  943.         case 2:
  944.             SN76477_update_2(param,buffer,length);
  945.             break;
  946.         case 3:
  947.             SN76477_update_3(param,buffer,length);
  948.             break;
  949.         case 4:
  950.             SN76477_update_4(param,buffer,length);
  951.             break;
  952.         case 5:
  953.             SN76477_update_5(param,buffer,length);
  954.             break;
  955.         case 6:
  956.             SN76477_update_6(param,buffer,length);
  957.             break;
  958.         default:
  959.             SN76477_update_7(param,buffer,length);
  960.             break;
  961.         }
  962.     }
  963. }
  964.  
  965. int SN76477_sh_start(const struct MachineSound *msound)
  966. {
  967.     int i;
  968.     intf = msound->sound_interface;
  969.  
  970.     for( i = 0; i < intf->num; i++ )
  971.     {
  972.         char name[16];
  973.  
  974.         sn76477[i] = malloc(sizeof(struct SN76477));
  975.         if( !sn76477[i] )
  976.         {
  977.             LOG(0,("%s failed to malloc struct SN76477\n", name));
  978.             return 1;
  979.         }
  980.         memset(sn76477[i], 0, sizeof(struct SN76477));
  981.  
  982.         sprintf(name, "SN76477 #%d", i);
  983.         sn76477[i]->channel = stream_init(name, intf->mixing_level[i], Machine->sample_rate, i, SN76477_sound_update);
  984.         if( sn76477[i]->channel == -1 )
  985.         {
  986.             LOG(0,("%s stream_init failed\n", name));
  987.             return 1;
  988.         }
  989.         sn76477[i]->samplerate = Machine->sample_rate ? Machine->sample_rate : 1;
  990.         /* set up interface (default) values */
  991.         SN76477_set_noise_res(i, intf->noise_res[i]);
  992.         SN76477_set_filter_res(i, intf->filter_res[i]);
  993.         SN76477_set_filter_cap(i, intf->filter_cap[i]);
  994.         SN76477_set_decay_res(i, intf->decay_res[i]);
  995.         SN76477_set_attack_decay_cap(i, intf->attack_decay_cap[i]);
  996.         SN76477_set_attack_res(i, intf->attack_res[i]);
  997.         SN76477_set_amplitude_res(i, intf->amplitude_res[i]);
  998.         SN76477_set_feedback_res(i, intf->feedback_res[i]);
  999.         SN76477_set_oneshot_res(i, intf->oneshot_res[i]);
  1000.         SN76477_set_oneshot_cap(i, intf->oneshot_cap[i]);
  1001.         SN76477_set_pitch_voltage(i, intf->pitch_voltage[i]);
  1002.         SN76477_set_slf_res(i, intf->slf_res[i]);
  1003.         SN76477_set_slf_cap(i, intf->slf_cap[i]);
  1004.         SN76477_set_vco_res(i, intf->vco_res[i]);
  1005.         SN76477_set_vco_cap(i, intf->vco_cap[i]);
  1006.         SN76477_set_vco_voltage(i, intf->vco_voltage[i]);
  1007.         SN76477_mixer_w(i, 0x07);        /* turn off mixing */
  1008.         SN76477_envelope_w(i, 0x03);    /* envelope inputs open */
  1009.         SN76477_enable_w(i, 0x01);        /* enable input open */
  1010.     }
  1011.     return 0;
  1012. }
  1013.  
  1014. void SN76477_sh_stop(void)
  1015. {
  1016.     int i;
  1017.     for( i = 0; i < intf->num; i++ )
  1018.     {
  1019.         if( sn76477[i] )
  1020.         {
  1021.             if( sn76477[i]->envelope_timer )
  1022.                 timer_remove(sn76477[i]->envelope_timer);
  1023.             free(sn76477[i]);
  1024.         }
  1025.         sn76477[i] = NULL;
  1026.     }
  1027. }
  1028.  
  1029. void SN76477_sh_update(void)
  1030. {
  1031.     int i;
  1032.     for( i = 0; i < intf->num; i++ )
  1033.         stream_update(i,0);
  1034. }
  1035.  
  1036.